﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using BackgroundTest.BasicAbstracts;

namespace BackgroundTest.BattleFieldManager
{    
    public class LandForms : GUIObjects
    {
        // The position on map
        public VectorMap landPosition { get; set; }

        // The height of the land form
        public int height { get; set; }

        // The texture of the wall
        public Texture2D[] textureWall;

        // The precision of z-buffer
        protected float zPrecision;

        /************************************************************************/
        /* Method name: Construction Function                                   */
        /* Parameters: Camera: the camera of the battle field.                  */
        /************************************************************************/
        public LandForms(Camera _camera,float _zPrecision)
            : base(_camera)
        {
            zPrecision = _zPrecision;
        }

        /************************************************************************/
        /* Method name: LoadWallTexture                                         */
        /* Parameters: Texture2D: the texture of wall.                          */
        /************************************************************************/
        public void LoadWallTexture(Texture2D _textureWall)
        {
            textureWall = new Texture2D[height];
            for (int i = 0; i < height; i++ )
            {
                textureWall[i] = _textureWall;
            }
        }

        public override void UpdatePosition( GameTime gametime )
        {
            position.x = landPosition.GetPosition().x;
            position.y = landPosition.GetPosition().y - height * BasicData.StairHeight;
            rectanglePosition = new Rectangle ( landPosition.GetPosition().x - camera.position.x,
                landPosition.GetPosition().y - height * BasicData.StairHeight - camera.position.y, 128, 128);
            timeSinceLastFrame = gametime.TotalGameTime.Milliseconds - timeSinceLastFrame;
        }

        public override void Render( SpriteBatch GUIBatch )
        {
            for (int i = 0; i < height; i++)
            {
                GUIBatch.Draw(textureWall[i],
                    new Rectangle(landPosition.GetPosition().x - camera.position.x,
                        landPosition.GetPosition().y - (height - i - 1) * BasicData.StairHeight - camera.position.y,
                        128, 128),
                    null,
                    Color.White,
                    0,
                    Vector2.Zero,
                    SpriteEffects.None,
                    zBuffer + zPrecision * 0.1f);
            }    
            GUIBatch.Draw(texture,
                    rectanglePosition,
                    null, 
                    Color.White, 
                    0, 
                    Vector2.Zero, 
                    SpriteEffects.None, 
                    zBuffer);
        }
    }

    public class LandformManager
    {
        // The minimum Z divergence of the landforms.
        public float zPrecision { set; get; }

        // The camera that used by all landforms.
        protected Camera camera;

        // The Main list of this object.
        public List<LandForms> landFormList;

        /************************************************************************/
        /* Method name: Construction Function                                   */
        /* Parameters: Camera: the camera of the battle field.                  */
        /************************************************************************/
        public LandformManager (Camera _camera)
        {
            landFormList = new List<LandForms>();
            camera = _camera;
        }

        // This function is used to initiate the landforms of the battle-field.
        // Revise is needed.
        public void InitiateLandform ( Texture2D _texture , Texture2D _textureWall, MapTabular _mapTabular )
        {
            zPrecision = Convert.ToSingle( 0.5 / (_mapTabular.HeightHeight + _mapTabular.HeightWidth));
            for (int i = 0; i < _mapTabular.HeightWidth; i++)
            {
                for (int j = 0; j < _mapTabular.HeightHeight; j++)
                {
                    using (LandForms tempLandform = new LandForms(camera,zPrecision))
                    {
                        tempLandform.LoadTexture(_texture);
                        tempLandform.landPosition = new VectorMap( i , j );
                        tempLandform.zBuffer = 1 - zPrecision * ( i + j + 1 );
                        tempLandform.height = _mapTabular.HeightTab[i,j];
                        tempLandform.LoadWallTexture(_textureWall);
                        landFormList.Add(tempLandform);
                    }
                }
            }
        }

        /************************************************************************/
        /* Method name: UpdateLandform                                          */
        /* Parameters: GameTime: the time elapsed.                              */
        /************************************************************************/
        public void UpdateLandform( GameTime gametime )
        {
            foreach (LandForms lf in landFormList)
            {
                lf.UpdatePosition( gametime );
            }
        }

        /************************************************************************/
        /* Method name: RenderLandform                                          */
        /* Parameters: SpriteBatch: the SpriteBatch used to Render.             */
        /************************************************************************/
        public void RenderLandform ( SpriteBatch _spriteBatch )
        {
            foreach (LandForms lf in landFormList)
            {                
                lf.Render(_spriteBatch );
            }
        }

        /************************************************************************/
        /* Method name: GetMouseMapPosition                                     */
        /* Parameters: VectorScreen: The position of the mouse.                 */
        /************************************************************************/
        public VectorMap GetMouseMapPosition(VectorScreen _vs)
        {
            foreach (LandForms lf in landFormList)
            {
                if (lf.Collided(_vs))
                {
                    return lf.landPosition;
                }
            }
            return VectorMap.False;
        }
    }
}
